package org.apache.sad.core.framework.spring;

import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;

import java.util.HashMap;
import java.util.Map;


public class AppContextSingletonBeanFactoryLocator extends ContextSingletonBeanFactoryLocator {

	private static final String DEFAULT_RESOURCE_LOCATION = "classpath*:beanRefContext.xml";
	
	private static final Map<ClassLoader, Map<String, BeanFactoryLocator>> appMap = new HashMap<ClassLoader, Map<String, BeanFactoryLocator>>();

	public static BeanFactoryLocator getAppInstance(Object appInstance) {
		String resourceLocation = DEFAULT_RESOURCE_LOCATION;

		if (!ResourcePatternUtils.isUrl(resourceLocation)) {
			resourceLocation = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resourceLocation;
		}

		Map<String, BeanFactoryLocator> instances;


		synchronized (appMap) {
			instances = (Map<String, BeanFactoryLocator>)appMap.get(appInstance.getClass().getClassLoader());
			if (instances == null) {
				appMap.put(appInstance.getClass().getClassLoader(),
						instances = new HashMap<String, BeanFactoryLocator>());
			}
		}

		synchronized (instances) {
			if (logger.isDebugEnabled()) {
				logger.debug("ContextSingletonBeanFactoryLocator.getInstance(): instances.hashCode=" + instances.hashCode() + ", instances=" + instances);
			}
			BeanFactoryLocator bfl = (BeanFactoryLocator) instances.get(resourceLocation);
			if (bfl == null) {
				bfl = new AppContextSingletonBeanFactoryLocator(resourceLocation);
				instances.put(resourceLocation, bfl);
			}
			return bfl;
		}

	}


	protected AppContextSingletonBeanFactoryLocator(String resourceLocation) {
		super(resourceLocation);
	}
}